import fs from 'fs';

const opusSource = "../demo.opus";
const outputDir = "./output_frames";

if(!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir);
}

function parseOpusFileWithHeader(data) {
    const view = new DataView(data.buffer);

    // 检查 "OpusHead" 标识
    const opusHead = String.fromCharCode(...data.slice(0, 8));
    if (opusHead !== "OpusHead") {
        throw new Error("不是有效的OPUS文件格式");
    }

    let offset = 8;

    // 读取版本号
    const version = data[offset++];
    console.log(`OPUS文件版本: ${version}`);

    // 读取通道数
    const channels = data[offset++];
    console.log(`通道数: ${channels}`);

    // 读取预跳过样本数
    const preSkip = view.getUint16(offset, true);
    offset += 2;
    console.log(`预跳过样本数: ${preSkip}`);

    // 读取采样率
    const sampleRate = view.getUint32(offset, true);
    offset += 4;
    console.log(`采样率: ${sampleRate}Hz`);

    // 读取输出增益
    const outputGain = view.getUint16(offset, true);
    offset += 2;
    console.log(`输出增益: ${outputGain}`);

    // 读取通道映射
    const channelMapping = data[offset++];
    console.log(`通道映射: ${channelMapping}`);

    // 读取自定义扩展信息
    const frameSize = view.getUint16(offset, true);
    offset += 2;
    console.log(`帧大小: ${frameSize}`);

    const totalFrames = view.getUint32(offset, true);
    offset += 4;
    console.log(`总帧数: ${totalFrames}`);

    // 读取所有OPUS帧
    const opusFrames = [];
    for (let i = 0; i < totalFrames; i++) {
        if (offset + 4 > data.length) break;

        const frameLength = view.getUint32(offset, true);
        offset += 4;

        if (offset + frameLength > data.length) break;

        const frameData = data.slice(offset, offset + frameLength);
        opusFrames.push(frameData);
        offset += frameLength;
    }

    console.log(`成功解析 ${opusFrames.length} 帧OPUS数据`);
    return opusFrames;
}

async function splitFrame(data) {
    try {     
        console.log(`文件大小: ${data.length} 字节`);

        const opusFrames = parseOpusFileWithHeader(data);
        console.log(`解析出 ${opusFrames.length} 个OPUS帧`);

        // 按配置的帧数分组
        const framesPerChunk = 1;
        const totalChunks = Math.ceil(opusFrames.length / framesPerChunk);
        
        console.log(`将生成 ${totalChunks} 个OPUS文件，每个文件包含 ${framesPerChunk} 帧`);

        const generatedFiles = [];
        let currentChunkFrames = [];

        // 一帧一帧发送，同时收集帧用于文件保存
        for (let i = 0; i < opusFrames.length; i++) {
            const frameData = opusFrames[i];   
            currentChunkFrames.push(frameData);
            if (currentChunkFrames.length === framesPerChunk || i === opusFrames.length - 1) {
                const chunkIndex = Math.floor(i / framesPerChunk);
                const outputPath = `${outputDir}/frame_${chunkIndex + 1}.opus`;
                
                fs.writeFileSync(outputPath, frameData);
                generatedFiles.push(outputPath);
                
                console.log(`保存文件 ${chunkIndex + 1}/${totalChunks}: ${outputPath} (${currentChunkFrames.length} 帧)`);
                currentChunkFrames = [];
            }
        }
        console.log(`文件保存完成：成功生成 ${generatedFiles.length} 个OPUS文件`);
        // console.log(`文件列表:`, generatedFiles);
    } catch (error) {
        console.error('处理OPUS数据失败:', error);
    }
}

async function main() {
    if(!fs.existsSync(opusSource)) {
        console.error("文件不存在");
        return;
    }

    const fileBuffer = fs.readFileSync(opusSource);
    console.log(fileBuffer);

    await splitFrame(fileBuffer);
}

main();